//go:build linux
// +build linux

package service

import (
	"fmt"
	"sync"
	"time"

	"gitee.com/liumou_site/go-network-monitoring/types"
	"gitee.com/liumou_site/go-network-monitoring/utils"
)

// ProcessNetworkService Linux进程网络监控服务
type ProcessNetworkService struct {
	mu                sync.RWMutex
	connections       map[string]*types.ProcessConnection  // 连接缓存，key为inode
	processStats      map[int32]*types.ProcessInfo         // 进程统计缓存
	processSpeedStats map[int32]*types.ProcessSpeedStats   // 进程速度统计
	trafficCache      map[int32]*types.ProcessTrafficCache // 流量缓存，用于速度计算
	lastUpdate        time.Time
	updateInterval    time.Duration
}

// NewProcessNetworkService 创建新的进程网络监控服务实例
func NewProcessNetworkService() *ProcessNetworkService {
	return &ProcessNetworkService{
		connections:       make(map[string]*types.ProcessConnection),
		processStats:      make(map[int32]*types.ProcessInfo),
		processSpeedStats: make(map[int32]*types.ProcessSpeedStats),
		trafficCache:      make(map[int32]*types.ProcessTrafficCache),
		updateInterval:    2 * time.Second,
	}
}

// GetProcessConnections 获取所有进程的连接信息
func (pns *ProcessNetworkService) GetProcessConnections() ([]types.ProcessConnection, error) {
	pns.mu.RLock()
	defer pns.mu.RUnlock()

	connections := make([]types.ProcessConnection, 0, len(pns.connections))
	for _, conn := range pns.connections {
		connections = append(connections, *conn)
	}

	return connections, nil
}

// GetProcessStats 获取指定进程的网络统计
func (pns *ProcessNetworkService) GetProcessStats(pid int32) (*types.ProcessInfo, error) {
	pns.mu.RLock()
	defer pns.mu.RUnlock()

	stats, exists := pns.processStats[pid]
	if !exists {
		return nil, nil
	}

	// 创建副本避免并发问题
	statsCopy := *stats
	return &statsCopy, nil
}

// GetAllProcessStats 获取所有进程的统计信息
func (pns *ProcessNetworkService) GetAllProcessStats() ([]types.ProcessInfo, error) {
	pns.mu.RLock()
	defer pns.mu.RUnlock()

	stats := make([]types.ProcessInfo, 0, len(pns.processStats))
	for _, proc := range pns.processStats {
		stats = append(stats, *proc)
	}

	return stats, nil
}

// Update 更新进程网络监控数据
func (pns *ProcessNetworkService) Update() error {
	pns.mu.Lock()
	defer pns.mu.Unlock()

	// 获取实际的网络连接数据
	err := pns.collectRealNetworkData()
	if err != nil {
		return fmt.Errorf("收集网络数据失败: %v", err)
	}

	// 更新进程流量统计和速度计算
	err = pns.updateProcessTrafficAndSpeed()
	if err != nil {
		return fmt.Errorf("更新进程流量统计失败: %v", err)
	}

	pns.lastUpdate = time.Now()
	return nil
}

// collectRealNetworkData 从系统实际采集网络数据
func (pns *ProcessNetworkService) collectRealNetworkData() error {
	// 清空现有数据
	for k := range pns.connections {
		delete(pns.connections, k)
	}
	for k := range pns.processStats {
		delete(pns.processStats, k)
	}

	// 读取 TCP 连接
	tcpConns, err := pns.readTCPConnections()
	if err != nil {
		return fmt.Errorf("读取TCP连接失败: %v", err)
	}

	// 读取 UDP 连接
	udpConns, err := pns.readUDPConnections()
	if err != nil {
		return fmt.Errorf("读取UDP连接失败: %v", err)
	}

	// 合并所有连接
	allConns := append(tcpConns, udpConns...)

	// 为每个连接查找对应的进程信息
	for _, conn := range allConns {
		pid, processName, executable, username := utils.FindProcessByInode(conn.Inode)
		if pid > 0 {
			conn.PID = pid
			conn.ProcessName = processName

			// 初始化连接的流量数据
			conn.BytesSent = 0
			conn.BytesRecv = 0
			conn.SpeedUp = 0
			conn.SpeedDown = 0

			// 更新格式化文本
			conn.BytesSentText = utils.FormatBytes(conn.BytesSent)
			conn.BytesRecvText = utils.FormatBytes(conn.BytesRecv)
			conn.SpeedUpText = utils.FormatSpeed(conn.SpeedUp)
			conn.SpeedDownText = utils.FormatSpeed(conn.SpeedDown)

			pns.connections[conn.Inode] = &conn

			// 更新进程统计信息
			utils.UpdateProcessStats(pns.processStats, pid, processName, executable, username, &conn)
		}
	}

	return nil
}

// readTCPConnections 读取TCP连接信息
func (pns *ProcessNetworkService) readTCPConnections() ([]types.ProcessConnection, error) {
	var connections []types.ProcessConnection

	// 读取 IPv4 TCP 连接
	ipv4Conns, err := utils.ParseNetFile("/proc/net/tcp", "tcp")
	if err != nil {
		return nil, fmt.Errorf("读取/proc/net/tcp失败: %v", err)
	}
	connections = append(connections, ipv4Conns...)

	// 读取 IPv6 TCP 连接
	ipv6Conns, err := utils.ParseNetFile("/proc/net/tcp6", "tcp6")
	if err != nil {
		// IPv6可能不可用，记录警告但不返回错误
		fmt.Printf("警告: 读取/proc/net/tcp6失败: %v\n", err)
	} else {
		connections = append(connections, ipv6Conns...)
	}

	return connections, nil
}

// readUDPConnections 读取UDP连接信息
func (pns *ProcessNetworkService) readUDPConnections() ([]types.ProcessConnection, error) {
	var connections []types.ProcessConnection

	// 读取 IPv4 UDP 连接
	ipv4Conns, err := utils.ParseNetFile("/proc/net/udp", "udp")
	if err != nil {
		return nil, fmt.Errorf("读取/proc/net/udp失败: %v", err)
	}
	connections = append(connections, ipv4Conns...)

	// 读取 IPv6 UDP 连接
	ipv6Conns, err := utils.ParseNetFile("/proc/net/udp6", "udp6")
	if err != nil {
		// IPv6可能不可用，记录警告但不返回错误
		fmt.Printf("警告: 读取/proc/net/udp6失败: %v\n", err)
	} else {
		connections = append(connections, ipv6Conns...)
	}

	return connections, nil
}

// GetLastUpdate 获取最后更新时间
func (pns *ProcessNetworkService) GetLastUpdate() time.Time {
	pns.mu.RLock()
	defer pns.mu.RUnlock()
	return pns.lastUpdate
}

// StartAutoUpdate 启动自动更新
func (pns *ProcessNetworkService) StartAutoUpdate(interval time.Duration) {
	go func() {
		ticker := time.NewTicker(interval)
		defer ticker.Stop()

		for range ticker.C {
			pns.Update()
		}
	}()
}

// updateProcessTrafficAndSpeed 更新进程流量统计和速度计算
func (pns *ProcessNetworkService) updateProcessTrafficAndSpeed() error {
	// 为每个有效进程采集流量数据
	for pid := range pns.processStats {
		// 获取进程流量快照
		currentSnapshot, err := utils.GetProcessTrafficStats(pid)
		if err != nil {
			// 记录错误但不中断整个更新过程
			continue
		}

		// 更新流量缓存
		cache, exists := pns.trafficCache[pid]
		if !exists {
			cache = &types.ProcessTrafficCache{
				Current: currentSnapshot,
			}
			pns.trafficCache[pid] = cache
		} else {
			// 将当前数据移动到前一次，新数据作为当前
			cache.Previous = cache.Current
			cache.Current = currentSnapshot
		}

		// 计算速度
		speedStats := utils.CalculateProcessSpeed(cache.Previous, cache.Current)
		pns.processSpeedStats[pid] = speedStats

		// 更新进程统计中的流量和速度数据
		if processStats, exists := pns.processStats[pid]; exists {
			processStats.TotalSent = currentSnapshot.TotalSent
			processStats.TotalRecv = currentSnapshot.TotalRecv
			processStats.SpeedUp = speedStats.UploadSpeedMbps
			processStats.SpeedDown = speedStats.DownloadSpeedMbps

			// 更新格式化文本
			processStats.TotalSentText = utils.FormatBytes(currentSnapshot.TotalSent)
			processStats.TotalRecvText = utils.FormatBytes(currentSnapshot.TotalRecv)
			processStats.SpeedUpText = speedStats.UploadSpeedText
			processStats.SpeedDownText = speedStats.DownloadSpeedText
		}
	}

	return nil
}

// GetProcessSpeedStats 获取进程速度统计
func (pns *ProcessNetworkService) GetProcessSpeedStats(pid int32) (*types.ProcessSpeedStats, error) {
	pns.mu.RLock()
	defer pns.mu.RUnlock()

	stats, exists := pns.processSpeedStats[pid]
	if !exists {
		return nil, nil
	}

	// 创建副本避免并发问题
	statsCopy := *stats
	return &statsCopy, nil
}

// GetAllProcessSpeedStats 获取所有进程的速度统计
func (pns *ProcessNetworkService) GetAllProcessSpeedStats() ([]types.ProcessSpeedStats, error) {
	pns.mu.RLock()
	defer pns.mu.RUnlock()

	stats := make([]types.ProcessSpeedStats, 0, len(pns.processSpeedStats))
	for _, speedStats := range pns.processSpeedStats {
		stats = append(stats, *speedStats)
	}

	return stats, nil
}
